package com.pkk.penguin.frame.know.java.interview.year2021.atguigu_20210226.blokedqueue;

import java.util.NoSuchElementException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 * 阻塞队列的测试
 *
 * @author peikunkun
 * @version V1.0
 * @date 2021-03-16 15:57
 **/
public class BlockQueueSimple {


  /**
   * synchronousQueue的使用
   *
   * @return void
   * @Param
   * @author peikunkun
   * @date 2021/3/16 0016 下午 4:09
   * @since
   */
  public void synchronousQueueTest() {
    System.out.println("欢迎使用单元测试方法【Administrator_15()_20210316155758】");
    System.out.println("此方法测试描述：【SynchronousQueue:不储存元素的队列,就是里面最多有一个元素,放进去之后再放就自动阻塞,取出一个再取也会阻塞】");

    SynchronousQueue synchronousQueue = new SynchronousQueue<Integer>();
    new Thread(() -> {
      try {
        Thread.sleep(3000);
        synchronousQueue.put(1);
        System.out.println("put finish");

        Thread.sleep(3000);
        synchronousQueue.put(2);
        System.out.println("put finish");

        Thread.sleep(3000);
        synchronousQueue.put(3);
        System.out.println("put finish");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }


    }, "AA").start();

    new Thread(() -> {
      try {
        synchronousQueue.take();
        System.out.println("take finish");

        synchronousQueue.take();
        System.out.println("take finish");

        synchronousQueue.take();
        System.out.println("take finish");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }


    }, "BB").start();
  }


  /**
   * 有界的数组队列
   *
   * @return void
   * @Param
   * @author peikunkun
   * @date 2021/3/16 0016 下午 4:22
   * @since
   */
  public void arrayBlockingQueue() {
    System.out.println("此方法测试描述：【ArrayBlockingQueue:有界数组队列】");

    ArrayBlockingQueue<Integer> arrayBlockingQueue = new ArrayBlockingQueue<Integer>(3);
    new Thread(() -> {
      try {
        Thread.sleep(3000);
        arrayBlockingQueue.put(1);
        System.out.println("put finish-->阻塞,满的话会堵塞");

        Thread.sleep(3000);
        arrayBlockingQueue.add(2);
        System.out.println("add finish-->满的话会抛出[Queue Full]异常");

        Thread.sleep(3000);
        arrayBlockingQueue.offer(3);
        System.out.println("offer finish-->会返回boolean值,成功与否");

        Thread.sleep(3000);
        arrayBlockingQueue.offer(4, 3000L, TimeUnit.MILLISECONDS);
        System.out.println("offer finish-->在一段时间之后还没有成功,会返回boolean值,成功与否(如果有空间,直接插入成功,无需等待)");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }


    }, "AA").start();

    new Thread(() -> {
      try {

        try {
          arrayBlockingQueue.remove();
          System.out.println("remove finish-->[抛出异常NoSuchElementException]");
        } catch (NoSuchElementException e) {
          e.printStackTrace();
          System.out.println("remove finish-->[抛出异常NoSuchElementException]");
        }

        arrayBlockingQueue.poll();
        System.out.println("poll finish-->返回boolean");

        arrayBlockingQueue.take();
        System.out.println("take finish-->阻塞");

        arrayBlockingQueue.poll(3000L, TimeUnit.MILLISECONDS);
        System.out.println("poll finish-->[等待一段时间,返回boolean]");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }


    }, "BB").start();
  }


  /**
   * 链表阻塞有界队列
   *
   * @return void
   * @Param
   * @author peikunkun
   * @date 2021/3/16 0016 下午 4:22
   * @since
   */
  public void linkedBlockingQueue() {
    System.out.println("此方法测试描述：【LinkedBlockingQueue:有界链表队列,但是界限太大,为Integer的最大值Integer.MAX_VALUE】");

    LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>(3);

    linkedBlockingQueue.add(1);
    linkedBlockingQueue.add(2);
    linkedBlockingQueue.add(3);
    linkedBlockingQueue.add(4);
    linkedBlockingQueue.add(5);


  }


  public static void main(String[] args) {
    new BlockQueueSimple().synchronousQueueTest();
    new BlockQueueSimple().arrayBlockingQueue();
    new BlockQueueSimple().linkedBlockingQueue();
  }


}
